package com.example.boot.modules.system.service;

import cn.hutool.core.util.StrUtil;
import com.example.starter.weixin.pojo.WxToken;
import com.example.starter.weixin.util.WxUtil;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;

/**
 * @author 王令
 * @since 2024/02/26 14:40
 */
@Service
@RequiredArgsConstructor
public class WeiXinService {

    public final RedisTemplate<String, String> stringRedisTemplate;
    private final RedissonClient redissonClient;

    private static final String WEI_XIN_ACCESS_TOKEN = "wei_xin:access_token";

    @Value("${com.example.weixin.appid}")
    private String appid;
    @Value("${com.example.weixin.secret}")
    private String secret;

    public String getAccessToken() {
        String accessToken = stringRedisTemplate.opsForValue().get(WEI_XIN_ACCESS_TOKEN);

        if (StrUtil.isBlank(accessToken)) {
            RLock lock = redissonClient.getLock(WEI_XIN_ACCESS_TOKEN);
            try {
                lock.lock();
                accessToken = stringRedisTemplate.opsForValue().get(WEI_XIN_ACCESS_TOKEN);
                if (StrUtil.isBlank(accessToken)) {
                    final WxToken wxToken = WxUtil.obtainAccessToken(appid, secret);
                    stringRedisTemplate.opsForValue().set(WEI_XIN_ACCESS_TOKEN, wxToken.getAccess_token(), Duration.ofHours(2));
                    accessToken = wxToken.getAccess_token();
                }
            } finally {
                lock.unlock();
            }
        }
        return accessToken;
    }
}
